package com.oauth.google.server.service;

import java.net.URL;
import java.util.List;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import com.google.gdata.client.authn.oauth.GoogleOAuthHelper;
import com.google.gdata.client.authn.oauth.GoogleOAuthParameters;
import com.google.gdata.client.authn.oauth.OAuthHmacSha1Signer;
import com.google.gdata.client.authn.oauth.OAuthSigner;
import com.google.gdata.client.photos.PicasawebService;
import com.google.gdata.data.photos.AlbumFeed;
import com.google.gdata.data.photos.GphotoEntry;
import com.google.gdata.data.photos.GphotoFeed;
import com.google.gdata.data.photos.PhotoEntry;
import com.google.gdata.data.photos.UserFeed;
import com.oauth.google.client.beans.picassa.GooglePicasaAlbum;
import com.oauth.google.client.beans.picassa.PicasaPhoto;
import com.oauth.google.server.conf.GoogleOAuthConfig;
import com.oauth.google.server.conf.PicasaInfoBean;
import com.oauth.google.server.constants.GoogleServiceType;
import com.oauth.google.server.shared.PicasaUtils;
import com.oauth.service.application.ApplicationService;
import com.oauth.service.global.beans.OAuthAccessToken;

@Service
public class PicasaOAuthServiceImpl extends AbstractGoogleOAuthService implements
		PicasaOAuthService {

	private GoogleOAuthHelper mOAuthHelper;
	private OAuthSigner mSigner;
	@Autowired
	private ApplicationService applicationService;

	@Autowired
	@Qualifier("picasaConfig")
	private GoogleOAuthConfig mOAuthConfigBean;

	@Autowired
	private PicasaInfoBean picasaInfoBean;

	@PostConstruct
	public void initialise() {
		mSigner = new OAuthHmacSha1Signer();
		mOAuthHelper = new GoogleOAuthHelper(mSigner);
	}

	/**
	 * @param pOAuthConfigBean
	 *            the oAuthConfigBean to set
	 */
	public void setOAuthConfigBean(GoogleOAuthConfig pOAuthConfigBean) {
		mOAuthConfigBean = pOAuthConfigBean;
	}

	private PicasawebService getPicasaService(Long pMemberId) throws Exception {
		GoogleOAuthParameters oauthParameters = getOAuthParameters();
		OAuthAccessToken accessToken = getAccessTokenFromDB(pMemberId);
		oauthParameters.setOAuthToken(accessToken.getToken());
		oauthParameters.setOAuthTokenSecret(accessToken.getTokenSecret());

		PicasawebService picasaService = new PicasawebService(
				GoogleServiceType.Picasa.getGoogleServiceName());
		// Set the OAuth credentials which were obtained from the step
		picasaService.setOAuthCredentials(oauthParameters, mSigner);
		return picasaService;
	}

	private <F extends GphotoFeed<F>> F getFeed(PicasawebService pPicasaService, Class<F> pClass)
			throws Exception {
		URL feedUrl = new URL(GoogleServiceType.Picasa.getFeedUrl());
		return pPicasaService.getFeed(feedUrl, pClass);
	}

	private <F extends GphotoFeed<F>> F getFeed(String pFeedUrl, Class<F> pClass,
			PicasawebService pPicasaService) throws Exception {
		URL feedUrl = new URL(pFeedUrl);
		return pPicasaService.getFeed(feedUrl, pClass);
	}

	@Override
	public List<GooglePicasaAlbum> getPicasaAlbums(Long pMemberId) throws Exception {
		PicasawebService picasaService = getPicasaService(pMemberId);
		UserFeed feed = getFeed(GoogleServiceType.Picasa.getFeedUrl() + "?kind=album",
				UserFeed.class, picasaService);
		List<GphotoEntry> entries = feed.getEntries();
		return PicasaUtils.getPicasaAlbums(entries);
	}

	@Override
	public List<PicasaPhoto> getPhotosForAlbum(Long pMemberId, String pAlbumId) throws Exception {
		PicasawebService picasaService = getPicasaService(pMemberId);
		AlbumFeed feed = getFeed(GoogleServiceType.Picasa.getFeedUrl() + "/albumid/" + pAlbumId,
				AlbumFeed.class, picasaService);
		List<PhotoEntry> photos = feed.getPhotoEntries();
		return PicasaUtils.getPhotos(photos);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.oauth.google.server.service.AbstractGoogleOAuthService#getApplicationKey
	 * ()
	 */
	@Override
	protected Long getApplicationKey() {
		return picasaInfoBean.getKey();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.oauth.google.server.service.AbstractGoogleOAuthService#
	 * getApplicationService()
	 */
	@Override
	protected ApplicationService getApplicationService() {
		return applicationService;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.oauth.google.server.service.AbstractGoogleOAuthService#getScope()
	 */
	@Override
	protected String getScope() {
		return GoogleServiceType.Picasa.getScope();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.oauth.google.server.service.AbstractGoogleOAuthService#getOAuthHelper
	 * ()
	 */
	@Override
	protected GoogleOAuthHelper getOAuthHelper() {
		return mOAuthHelper;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.oauth.google.server.service.AbstractGoogleOAuthService#getOAuthConfigBean
	 * ()
	 */
	@Override
	protected GoogleOAuthConfig getOAuthConfigBean() {
		return mOAuthConfigBean;
	}

}
